package com.lhl.netty.server;

import com.lhl.netty.common.ExceptionUtil;
import com.lhl.netty.common.NetMessage;
import com.lhl.netty.common.NetMessageType;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NetServerHandler extends ChannelInboundHandlerAdapter { // (1)
    private final static Logger logger = LoggerFactory.getLogger(NetServerHandler.class);
    private NetServer netServer;

    public NetServerHandler(NetServer netServer) {
        this.netServer = netServer;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        netServer.routing(ctx.channel(),(NetMessage)msg);
    }

    @Override
    public void channelActive(final ChannelHandlerContext ctx) {
        netServer.routing(ctx.channel(),new NetMessage(NetMessageType.MESSAGE_WELCOME,"welcome"));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
        // Close the connection when an exception is raised.
        try{
            ctx.close();
            logger.error(cause.getMessage());
            cause.printStackTrace();
        }catch(Exception e){
            logger.error(ExceptionUtil.getMessage(e));
            e.printStackTrace();
        }
    }

    /**
     * 一段时间未进行读写操作 发送心跳包,客户端不返回心跳包则断开连接
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        super.userEventTriggered(ctx, evt);

        if (evt instanceof IdleStateEvent) {

            IdleStateEvent event = (IdleStateEvent) evt;

            if (event.state().equals(IdleState.READER_IDLE)) {
                // 未进行读操作 超时关闭channel
                ctx.close();
            } else if (event.state().equals(IdleState.WRITER_IDLE)) {


            } else if (event.state().equals(IdleState.ALL_IDLE)) {
                //未进行读写 发送心跳消息
                ctx.writeAndFlush(new NetMessage(NetMessageType.MESSAGE_HEARTBEAT,""));
            }

        }
    }

    /**
     * 客户端断线
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        netServer.routing(ctx.channel(),new NetMessage(NetMessageType.MESSAGE_DISCONNECTED,""));
    }
}